package com.example.mybatispluslearning.generator;

import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;

import java.util.Scanner;

/**
 * 主要参考官方文档以及部分源码
 */
public class CodeGenerator {

    /**
     * <p>
     * 读取控制台内容
     * mybatis-plus 版本3.5.0(不适合3.5.1及以上的),采用默认模板引擎
     * </p>
     */
    public static String scanner(String tip) {
        Scanner scanner = new Scanner(System.in);
        StringBuilder help = new StringBuilder();
        help.append("请输入" + tip + "：");
        System.out.println(help.toString());
        if (scanner.hasNext()) {
            String ipt = scanner.next();
            if (StringUtils.isNotBlank(ipt)) {
                return ipt;
            }
        }
        throw new MybatisPlusException("请输入正确的" + tip + "！");
    }

    public static void main(String[] args) {
        /*---------------------------数据源配置---------------------------*/
        //定义数据源的一些基本信息
        String url="jdbc:mysql://localhost:3306/你的数据库名字?useUnicode=true&useSSL=false&characterEncoding=utf8";
        String username="****用户名*****";
        String password="*****密码*****";
        DataSourceConfig dc = new DataSourceConfig.Builder(url, username, password).build();

        /*---------------------------全局配置---------------------------*/
        //定义该项目的路径以及输出文件目录,如果是自定义生成代码文件位置，outpurDir可以不需要
        String projectPath=System.getProperty("user.dir");
        String outputDir=projectPath+"/src/main/java";
        String author="*****作者*****";
        GlobalConfig.Builder gcBuilder = new GlobalConfig.Builder();
        GlobalConfig gc = gcBuilder.openDir(false)
                .outputDir(outputDir)
                .author(author).build();

        /*---------------------------策略配置---------------------------*/
        //定义了生成代码的一些细节
        StrategyConfig.Builder strategyBuilder = new StrategyConfig.Builder();
        StrategyConfig strategy = strategyBuilder.addInclude(scanner("输入表名，逗号隔开").split(",")) //希望对哪些表进行处理(可以写多个)，该函数必须在strategyBuilder后进行设置
                .entityBuilder() //以下是实体类的设置,如果想对service，mapper可以从.serviceBuilder()后开始
                .enableLombok() //使用lombok插件
                .superClass("com.example.mybatispluslearning.dao.base.BaseEntity")  //让实体类继承某一个base类，该base类拥有所有实体类的公共信息
                                                                    //如：创建时间，修改时间，id等
                .naming(NamingStrategy.underline_to_camel) //数据库表名映射到实体类名称
                .columnNaming(NamingStrategy.underline_to_camel) //数据库字段名称映射到实体类属性名称
                .logicDeleteColumnName("deleted")   //逻辑删除的字段，没有可以不写
                .versionColumnName("version") //乐观锁字段（版本号），没有可以不写
                .build();


        /*---------------------------包配置---------------------------*/
        //定义了生成文件的包信息
        PackageConfig.Builder packageBuilder = new PackageConfig.Builder();
        PackageConfig pc = packageBuilder.moduleName(scanner("模块名"))
                .parent("父模块名")
                .entity("pojo") //实体类包名,其他的方法service,controller,mapper...都类似
                .build();

        //以上方式会使得xml,mapper,entiry...等文件放到一起，为了更加模块化，有时候希望把他们分开放，可使用如下方式
        //但是！！！该方式会使得生成的代码块的模块为默认的，而这会产生错误，需要我们修改一下，idea中alt+enter直接一个个设置
        //就行，也挺快的(目前没有找到解决方案)
        /*
                //不同文件的路径
        Map<String,String> pathInfo=new HashMap<>();
        String entityPath="实体类的路径";
        String controllerPath="controller的路径";
        String mapperPath="mapper的路径";
        String xmlPath="xml的路径";
        String servicePath="service的路径";
        String impPath="imp的路径";
        pathInfo.put(ConstVal.ENTITY_PATH,entityPath);
        pathInfo.put(ConstVal.CONTROLLER_PATH,controllerPath);
        pathInfo.put(ConstVal.MAPPER_PATH,mapperPath);
        pathInfo.put(ConstVal.XML_PATH,xmlPath);
        pathInfo.put(ConstVal.SERVICE_PATH,servicePath);
        pathInfo.put(ConstVal.SERVICE_IMPL_PATH,impPath);
        
        PackageConfig.Builder packageBuilder = new PackageConfig.Builder();
        PackageConfig pc = packageBuilder.pathInfo(pathInfo).build();
        */

        // 代码生成器
        AutoGenerator mpg = new AutoGenerator(dc);
        mpg.strategy(strategy)
                .global(gc)
                .packageInfo(pc);

        mpg.execute();
    }

}
